using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace XeoEngine
{
    abstract class MenuScreen : GameScreen
    {
        MouseState oldms = new MouseState();
        List<MenuEntry> menuEntries = new List<MenuEntry>();
        public int selectedEntry = 0;
        string menuTitle;
        protected IList<MenuEntry> MenuEntries
        {
            get { return menuEntries; }
        }

        protected string MenuTitle
        {
            get { return menuTitle; }
            set { menuTitle = value; }
        }

        public MenuScreen(string menuTitle)
        {
            this.menuTitle = menuTitle;

            TransitionOnTime = TimeSpan.FromSeconds(0.5);
            TransitionOffTime = TimeSpan.FromSeconds(0.5);
        }

        public override void HandleInput(InputState input)
        {
            ScreenManager.game.Window.Title = "Light Hunter - " + menuTitle;
            if (input.IsMenuUp(ControllingPlayer))
            {
                selectedEntry--;
                ScreenManager.soundBank.PlayCue("UI_Click");
                if (selectedEntry < 0)
                    selectedEntry = menuEntries.Count - 1;
            }
            if (input.IsMenuDown(ControllingPlayer))
            {
                selectedEntry++;
                ScreenManager.soundBank.PlayCue("UI_Click");
                if (selectedEntry >= menuEntries.Count)
                    selectedEntry = 0;
            }
            PlayerIndex playerIndex;
            MouseState ms = Mouse.GetState();
            for (int i = 0; i < menuEntries.Count; i++)
            {
                if (ms.Y > menuEntries[i].Position.Y - 20 && ms.Y < menuEntries[i].Position.Y + menuEntries[i].GetHeight(this) - 20 && ms.X > menuEntries[i].Position.X && ms.X < menuEntries[i].Position.X + menuEntries[i].GetWidth(this))
                {
                    if (selectedEntry != i)
                    {
                        selectedEntry = i;
                        ScreenManager.soundBank.PlayCue("UI_Click");
                    }
                    if (ms.LeftButton == ButtonState.Pressed && oldms.LeftButton == ButtonState.Released)
                    {
                        OnSelectEntry(i, PlayerIndex.One);
                        selectedEntry = 0;
                    }
                    break;
                }
            }
            if (input.IsMenuSelect(ControllingPlayer, out playerIndex))
            {
                OnSelectEntry(selectedEntry, playerIndex);
            }
            else if (input.IsMenuCancel(ControllingPlayer, out playerIndex))
            {
                OnCancel(playerIndex);
            }
            oldms = ms;
        }

        protected virtual void OnSelectEntry(int entryIndex, PlayerIndex playerIndex)
        {
            menuEntries[entryIndex].OnSelectEntry(playerIndex);
            ScreenManager.soundBank.PlayCue("UI_Next");
        }

        protected virtual void OnCancel(PlayerIndex playerIndex)
        {
            ScreenManager.soundBank.PlayCue("UI_Back");
            ExitScreen();
        }

        protected void OnCancel(object sender, PlayerIndexEventArgs e)
        {
            OnCancel(e.PlayerIndex);
        }

        protected virtual void UpdateMenuEntryLocations()
        {
            float transitionOffset = (float)Math.Pow(TransitionPosition, 2);
            Vector2 position = new Vector2(0f, 175f);
            for (int i = 0; i < menuEntries.Count; i++)
            {
                MenuEntry menuEntry = menuEntries[i];
                position.X = ScreenManager.GraphicsDevice.Viewport.Width / 2 - menuEntry.GetWidth(this) / 2;
                if (ScreenState == ScreenState.TransitionOn) position.X -= transitionOffset * 256;
                else position.X += transitionOffset * 512;
                menuEntry.Position = position;
                position.Y += menuEntry.GetHeight(this);
            }
        }

        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
            for (int i = 0; i < menuEntries.Count; i++)
            {
                bool isSelected = IsActive && (i == selectedEntry);
                menuEntries[i].Update(this, isSelected, gameTime);
            }
        }

        public override void Draw(GameTime gameTime)
        {
            UpdateMenuEntryLocations();
            GraphicsDevice graphics = ScreenManager.GraphicsDevice;
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
            SpriteFont font = ScreenManager.Font;
            spriteBatch.Begin();
            for (int i = 0; i < menuEntries.Count; i++)
            {
                MenuEntry menuEntry = menuEntries[i];
                bool isSelected = IsActive && (i == selectedEntry);
                menuEntry.Draw(this, isSelected, gameTime);
            }
            float transitionOffset = (float)Math.Pow(TransitionPosition, 2);
            Vector2 titlePosition = new Vector2(graphics.Viewport.Width / 2, 80);
            Vector2 titleOrigin = font.MeasureString(menuTitle) / 2;
            Color titleColor = new Color(0, 170, 255) * TransitionAlpha;
            float titleScale = 1.25f;
            titlePosition.Y -= transitionOffset * 100;
            spriteBatch.DrawString(font, menuTitle, titlePosition, titleColor, 0, titleOrigin, titleScale, SpriteEffects.None, 0);
            spriteBatch.End();
        }
    }
}
